﻿/*----------------------------------------------------------------
// 公司名称：公司名称
// 
// 产品名称：Gaf
//
// 创 建 人：netcasewqs
// 创建日期：2022/3/4
// 邮    箱：netcasewqs@qq.com
//
// Copyright (C) 2022 Gaf，保留所有权利。
//
//----------------------------------------------------------------*/

namespace Gaf.Impl;

internal class AddinDescriptorLoader
{
    /// <summary>
    /// 解析的状态字典
    /// </summary>
    private readonly List<AddinDescriptor> Items = new();

    private readonly List<string> _errorMessages;
    private readonly HashSet<FileInfo> ManifestFiles = new();

    private AddinDescriptorLoader(List<string> errorMessages)
    {
        _errorMessages = errorMessages;
    }

    private AddinDescriptor[] Load(string rootDirectory)
    {
        DiscoveAddinDescription(rootDirectory);

        foreach (var manifestFile in ManifestFiles)
            LoadAddinDescription(manifestFile);
        return Items.OrderBy(p => p.StartLevel).ToArray();
    }

    public static AddinDescriptor[] Load(string rootDirectory, List<string> errorMessages)
    {
        AddinDescriptorLoader instance = new(errorMessages);
        return instance.Load(rootDirectory);
    }

    private void DiscoveAddinDescription(string rootDirectory)
    {
        var files = Directory.GetFiles(rootDirectory, Constants.ManifestFileName, SearchOption.AllDirectories).Select(p => new FileInfo(p));
        foreach (var file in files)
        {
            ManifestFiles.Add(file);
        }
    }

    private void LoadAddinDescription(FileInfo file)
    {
        try
        {
            var cfg = new ConfigurationBuilder()
            .AddIniFile(file.FullName)
            .Build();

            cfg.Providers.FirstOrDefault()?.Set(nameof(IAddin.Location), file.DirectoryName);

            var desc = cfg.Get<AddinDescriptor>();

            if (desc != null)
            {
                //desc.Location = file.DirectoryName!;

                desc.Manifest = cfg;

                if (string.IsNullOrEmpty(desc.Name))
                    _errorMessages.Add($"插件清单文件:{file.FullName} 配置错误， 'Name‘ 属性不允许为空.");
                Items.Add(desc);
            }

        }
        catch (Exception ex)
        {
            _errorMessages.Add($"解析清单文件错误： '{file.FullName}' ，错误原因:{ex.Message}");
        }



    }
}
